#include "../ControlUI/WebsocketClient.hpp"
#include "../ControlUI/NetworkConnect.hpp"
#include "../ControlUI/RecordListReader.hpp"
#include "../ControlUI/UI.hpp"
#include <iostream>
#include <stdexcept>

std::unique_ptr<NetworkConnect> conn;
UI ui;

class RecordRunner
{
  private:
    std::list<long> recordList;
    decltype(recordList)::iterator ptr;
  public:
    RecordRunner(std::string filepath)
    {
      recordList=GetStudentList(filepath);
      ptr=recordList.begin();
    }
    typedef std::tuple<std::string,long,std::string> peopleInf ;
    peopleInf Next()
    {
      if(std::next(ptr)==recordList.end())
        throw std::out_of_range("out of max");
      ptr++;
      return std::make_tuple<>(conn->GetStudentInf(*ptr),*ptr,"Boy");
    }
    peopleInf Last()
    {
      if(ptr==recordList.begin())
        throw std::out_of_range("out of max");
      ptr--;
      return std::make_tuple<>(conn->GetStudentInf(*ptr),*ptr,"Boy");
    }
    peopleInf Current()
    {
      return std::make_tuple<>(conn->GetStudentInf(*ptr),*ptr,"Boy");
    }
    long CurrentID()
    {
      return *ptr;
    }
    long GetSize()
    {
      return recordList.size();
    }
};

std::optional<RecordRunner> recordRunner=std::nullopt;
long RecordID=0;
std::string recordName;
long recordCounter=0;

int main(int argc,char** argv)
{
  ui.funcSetServerIPAddr=[](std::string host){
    conn.reset(new NetworkConnect(host));
  };
  ui.funcPage1Ready=[](const std::string& proj_name,const std::string& list_file){
    recordName=proj_name;
    RecordID=conn->CreateTask(proj_name);
    recordRunner=std::make_optional<RecordRunner>(RecordRunner(list_file));
  };
  ui.funcGetLastPeople=[](){
    auto val=recordRunner->Last();
    recordCounter--;
    return val;
  };
  ui.funcGetNextPeople=[](){
    auto val=recordRunner->Next();
    recordCounter++;
    return val;
  };
  ui.funcGetCurrentPeople=[](){
    return recordRunner->Current();
  };
  ui.funcGetRecordInfo=[](){
    return std::make_tuple<>(recordName,"长拳",recordCounter,recordRunner->GetSize());
  };
  ui.funcGetAllRecord=[](){
    return recordCounter;
  };
  ui.funcRecordControl=[](bool val){
    if(val)
    {
      conn->StartShot(RecordID,recordRunner->CurrentID());
    }
    else
    {
      conn->StopShot();
    }
  };
  ui.Boot();
}
